package com.kkwrite.regimen.provider.service.order;

import com.kkwrite.regimen.common.entity.dto.OutDTO;
import com.kkwrite.regimen.common.entity.dto.order.OrderChangePayStatusInDTO;
import com.kkwrite.regimen.common.entity.dto.order.OrderCountOutDTO;
import com.kkwrite.regimen.common.entity.dto.order.OrderDetailDTO;
import com.kkwrite.regimen.common.entity.dto.order.OrderPageableOutDTO;
import com.kkwrite.regimen.common.entity.dto.order.OrderReviewSubmitInDTO;
import com.kkwrite.regimen.common.entity.dto.order.RefundOutDTO;
import com.kkwrite.regimen.common.entity.dto.order.SubmitOrderInDTO;
import com.kkwrite.regimen.provider.domain.RegOrderDO;
import com.kkwrite.regimen.provider.exception.DBNullException;
import com.kkwrite.regimen.provider.exception.OrderCannotCancelException;
import com.kkwrite.regimen.provider.exception.OrderRefundException;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/** 
 * 订单服务
 *
 * @author Soosky Wang
 * @date 2018年7月21日 下午6:29:07 
 * @version 1.0.0
 */
public interface OrderService {

    /**
     * 根据订单编号查询订单
     * @param orderCode 订单编号
     * @return Optional&lt;RegOrderDO&gt;
     */
    Optional<RegOrderDO> findByOrderCode(String orderCode);

    /**
     * 根据ItemId查询订单
     * @param itemId 项目Id
     * @return list&lt;RegOrderDO&gt;，按创建时间倒序排列
     */
    List<RegOrderDO> findByItemId(Integer itemId);

    /**
     * 根据orderCode查询订单详情
     * @param orderCode 订单编号
     * @return OrderDetailDTO
     * @throws DBNullException 查询数据为空
     */
	OrderDetailDTO getDetailByCode(String orderCode) throws DBNullException;

	/**
     * 提交订单评价信息
     * @param reviewData 订单评价数据
     * @return OutDTO
     * @throws DBNullException 查询数据库为空
     */
    OutDTO submitReview(OrderReviewSubmitInDTO reviewData) throws DBNullException;

    /**
     * 根据订单编号查询订单评价
     * @param orderCode 订单编号
     * @return OutDTO&lt;OrderReviewQueryOutDTO&gt;
     */
    OutDTO queryReview(String orderCode);

    /**
     * 生成并保存新订单
     * @param inDTO 订单信息
     * @param userId 用户标识
     * @return OutDTO&lt;String&gt; data传订单号
     */
    OutDTO<String> save(SubmitOrderInDTO inDTO, Integer userId);

    /**
     * 更新订单支付状态
     * @param map 入参
     * @return 返回成功或失败
     */
    OutDTO updatePayStatus(Map<String, String> map);

    /**
     * 根据订单号取消订单
     * @param orderCode 订单编号
     * @throws DBNullException 查询数据为空
     * @throws OrderCannotCancelException 订单不能取消
     */
    void cancel(String orderCode) throws DBNullException, OrderCannotCancelException;

    /**
     * 更新订单服务状态
     * @param orderCode 订单编号
     * @param type 变更服务类型，type为0服务结束，type为1服务开始
     * @throws DBNullException 查询数据为空
     */
    void changeServiceStatus(String orderCode, Integer type) throws DBNullException;

    /**
     * 分页查询订单
     * @param page 页码
     * @param pageSize 每页大小
     * @param userId 用户ID
     * @param shopId 店铺ID
     * @param status 订单状态，可为空
     * @return OrderPageableOutDTO
     * @throws DBNullException 查询数据库为空
     */
    OrderPageableOutDTO queryOrderPageable(Integer page, Integer pageSize, Integer userId,
                                           Integer shopId, Short status) throws DBNullException;

    /**
     * 分页查询订单
     * @param page 页码
     * @param pageSize 每页大小
     * @param userId 用户ID
     * @param shopId 店铺ID
     * @param status 订单状态，可为空
     * @return OrderPageableOutDTO
     * @throws DBNullException 查询数据库为空
     */
    OrderPageableOutDTO queryOrderPageable(Integer page, Integer pageSize, Integer userId,
                                           Integer shopId, Short status, Short orderType) throws DBNullException;

    /**
     * 发起订单退款
     * @param orderCode 订单编号
     * @return RefundOutDTO
     * @throws DBNullException 查询数据为空
     * @throws OrderRefundException 订单退款操作异常
     */
    RefundOutDTO refund(String orderCode) throws DBNullException, OrderRefundException;

    /**
     * 继续支付业务处理
     * @param orderCode 订单编号
     * @return Map&lt;String, String&gt;
     * @throws DBNullException 查询数据为空
     */
    Map<String, String> continuePay(String orderCode) throws DBNullException;

    /**
     * 更新订单交易状态（支付状态、退款状态等）
     * @param paramMap 入参map
     */
    void updateTradeState(Map<String, String> paramMap);

    /**
     * 退款通知更新订单
     * @param paramMap 入参map
     * @throws DBNullException 查询数据为空
     */
    void updateRefundInfo(Map<String, String> paramMap) throws DBNullException;

    /**
     * 订单汇总统计
     * @param userId 用户ID
     * @return OrderCountOutDTO
     */
    OrderCountOutDTO count(String userId);

    /**
     * 订单汇总统计
     * @param userId 用户ID
     * @param orderType 订单类型
     * @return OrderCountOutDTO
     */
    OrderCountOutDTO count(String userId, Short orderType);

    /**
     * 更改订单的支付状态
     * @param inDTO 含入参订单编号和支付状态
     * @throws DBNullException 订单不存在
     */
    void changePayStatus(OrderChangePayStatusInDTO inDTO) throws DBNullException;

    /**
     * 统计商铺订单
     * @param shopId 店铺ID
     * @return OrderCountOutDTO
     */
    OrderCountOutDTO countByShopId(Long shopId);

    /**
     * 分页查询除了待支付状态的订单
     * @param shopIdString 店铺ID字符串
     * @param page 页码
     * @param pageSize 每页大小
     * @return OrderPageableOutDTO
     */
    OrderPageableOutDTO queryOrderPageableExceptUnpay(String shopIdString, Integer page, Integer pageSize);
}
